package test.evaluator
{
	import flash.geom.Point;
	
	import librus.cheeseChaser.components.PointEvaluator;
	import librus.cheeseChaser.tile.Tile;
	import librus.cheeseChaser.tile.TileModel;
	import librus.cheeseChaser.tile.TileType;
	
	import org.flexunit.asserts.assertEquals;

	public class EvaluatorTest
	{
		private var helper:EvaluatorTestHelper;
		[Before]
		public function startup():void
		{
			helper = new EvaluatorTestHelper;
		}
		
		[After]
		public function tearDown():void
		{
			helper = null;
		}
		
		[Test]
		public function trapTest():void
		{
			helper.add(getTile(TileType.TRAP, 0,0));
			helper.add(getTile(TileType.MOUSE_BROWN, 1,0));
			helper.add(getTile(TileType.MOUSE_GREY,  -1,0));
			helper.add(getTile(TileType.MOUSE_BROWN, 0,1));
			
			//1 trap 3 mouses - trap not closed
			var evaluator:PointEvaluatorT = new PointEvaluatorT(helper.map,helper.list);
			assertEquals(false,evaluator.callCheckTrap(helper.list[0] as TileModel));
						
			//1 trap 4 mouses - trap closed
			helper.add(getTile(TileType.MOUSE_BROWN, 0,-1));
			evaluator.tileMap = helper.map;
			assertEquals(true,evaluator.callCheckTrap(helper.list[0] as TileModel));
			
			//1 trap 4 mouses 1 cat - trap not closed
			helper.add(getTile(TileType.CAT, 1,1));
			evaluator.tileMap = helper.map;
			evaluator.tileList = helper.list;
			evaluator.callHandleCat(helper.list[helper.list.length-1] as TileModel);
			assertEquals(false,evaluator.callCheckTrap(helper.list[0] as TileModel));
			evaluator.callResetTiles();		
			
			helper.clean();				
		}
		
		[Test]
		public function catTest():void
		{			
			//seems like this 
			//    MTM
			//    MCM
			//    MHM
			//M-mouse, C-cat, H-cheese,T-trap
			
			helper.add(getTile(TileType.CAT,0,0));
			
			helper.add(getTile(TileType.MOUSE_BROWN,1,0));
			helper.add(getTile(TileType.MOUSE_GREY,-1,0));
			helper.add(getTile(TileType.CHEESE,0,1));
			helper.add(getTile(TileType.TRAP,0,-1));
			
			helper.add(getTile(TileType.MOUSE_BROWN,1,1));
			helper.add(getTile(TileType.MOUSE_GREY,1,-1));
			helper.add(getTile(TileType.MOUSE_BROWN,-1,1));
			helper.add(getTile(TileType.MOUSE_BROWN,-1,-1));
			
			var evaluator:PointEvaluatorT = new PointEvaluatorT(helper.map, helper.list);
				evaluator.callHandleCat(helper.list[0] as TileModel);
				
			var tmp:TileModel;
			
			var activeMouse:int=0;
			var deactiveMouse:int=0;
			var activeMisc:int =0;
			var deactiveMisc:int =0;
			
			for (var i:int=0;i<helper.list.length;i++)	
			{
				tmp = helper.list[i] as TileModel;
				
				if (tmp.isMouse())
				{
					if (tmp.active)
						activeMouse++;
					else
						deactiveMouse++;					
				}
				else
				{
					if (tmp.active)
						activeMisc++;
					else
						deactiveMisc++;
				}					
			}
			
			assertEquals(4,activeMouse);
			assertEquals(2,deactiveMouse);
			assertEquals(3,activeMisc);
			assertEquals(0,deactiveMisc);		
			
			helper.clean();
		}
		
		[Test]
		public function mouseTest():void
		{
			helper.add(getTile(TileType.MOUSE_BROWN,0,0));
			helper.add(getTile(TileType.MOUSE_BROWN,1,0));
			helper.add(getTile(TileType.MOUSE_BROWN,2,0));
			helper.add(getTile(TileType.MOUSE_BROWN,3,0));
			
			var mouseList:Array = helper.list.concat();						
			
			var evaluator:PointEvaluatorT = new PointEvaluatorT(helper.map, helper.list);
				evaluator.callHandleMouse(mouseList);
			
			//just mouse	
			assertEquals(4,evaluator.mousePoints);
			assertEquals(0,evaluator.cheeseBonusPoints);
						
			//we add one cheese to second mouse
			helper.add(getTile(TileType.CHEESE,1,1));	
			
			evaluator.tileMap = helper.map;
			evaluator.callHandleMouse(mouseList);
			
			assertEquals(4,evaluator.mousePoints);
			assertEquals(1,evaluator.cheeseBonusPoints);
			
			//we add two cheese to third mouse
			helper.add(getTile(TileType.CHEESE,2,-1));			
			helper.add(getTile(TileType.CHEESE,2,1));
			
			evaluator.tileMap = helper.map;
			evaluator.callHandleMouse(mouseList);
			
			assertEquals(4,evaluator.mousePoints);
			assertEquals(2,evaluator.cheeseBonusPoints);
			
			//finaly we add two cheese and a cat to forth mouse 
			helper.add(getTile(TileType.CHEESE,3,-1));			
			helper.add(getTile(TileType.CHEESE,3,1));			
			helper.add(getTile(TileType.CAT,4,0));
			
			evaluator.tileMap = helper.map;
			evaluator.callHandleCat(helper.list[helper.list.length-1] as TileModel);
			evaluator.callHandleMouse(mouseList);
			
			assertEquals(3,evaluator.mousePoints);
			assertEquals(2,evaluator.cheeseBonusPoints);
			helper.clean();
		}
		
		[Test]
		public function cheeseTest():void
		{
			// M
			//MHMM
			// MHHM
			// MHHM    
			//  MM
			
			helper.add(getTile(TileType.CHEESE,0,0));
			helper.add(getTile(TileType.CHEESE,1,1));
			helper.add(getTile(TileType.CHEESE,1,2));
			helper.add(getTile(TileType.CHEESE,2,1));
			helper.add(getTile(TileType.CHEESE,2,2));
			
			var cheeseList:Array = helper.list.concat();
			
			helper.add(getTile(TileType.MOUSE_BROWN,0,-1));
			helper.add(getTile(TileType.MOUSE_BROWN,-1,0));
			helper.add(getTile(TileType.MOUSE_BROWN,1,0));						
			var evaluator:PointEvaluatorT = new PointEvaluatorT(helper.map, helper.list);
			assertEquals(0,evaluator.callCheckCheese(cheeseList[0] as TileModel));
			evaluator.callResetTiles();
						
			helper.add(getTile(TileType.MOUSE_BROWN,0,1));
			evaluator.tileMap = helper.map;			
			assertEquals(1,evaluator.callCheckCheese(cheeseList[0] as TileModel));
			evaluator.callResetTiles();
			
			helper.add(getTile(TileType.MOUSE_BROWN,2,0));
			helper.add(getTile(TileType.MOUSE_BROWN,3,1));
			helper.add(getTile(TileType.MOUSE_BROWN,3,2));
			helper.add(getTile(TileType.MOUSE_BROWN,2,3));
			helper.add(getTile(TileType.MOUSE_BROWN,1,3));
			
			evaluator.tileMap = helper.map;			
			assertEquals(0,evaluator.callCheckCheese(cheeseList[1] as TileModel));
			evaluator.callResetTiles();
			assertEquals(0,evaluator.callCheckCheese(cheeseList[2] as TileModel));
			evaluator.callResetTiles();
			assertEquals(0,evaluator.callCheckCheese(cheeseList[3] as TileModel));
			evaluator.callResetTiles();
			assertEquals(0,evaluator.callCheckCheese(cheeseList[4] as TileModel));
			evaluator.callResetTiles();
			
			
			helper.add(getTile(TileType.MOUSE_BROWN,0,2));
			evaluator.tileMap = helper.map;			
			assertEquals(4,evaluator.callCheckCheese(cheeseList[1] as TileModel));
			evaluator.callResetTiles();
			assertEquals(4,evaluator.callCheckCheese(cheeseList[2] as TileModel));
			evaluator.callResetTiles();
			assertEquals(4,evaluator.callCheckCheese(cheeseList[3] as TileModel));
			evaluator.callResetTiles();
			assertEquals(4,evaluator.callCheckCheese(cheeseList[4] as TileModel));
			evaluator.callResetTiles();
			
			evaluator.callHandleCheese(cheeseList);
			assertEquals(90,evaluator.cheesePoints);
			
			helper.clean();
		}
		
		[Test]
		public function complexCheeseTest():void
		{
			//   MM
			//  MHHMMMMM
			// MHHHHHHHHM
			//  MHMMMHMM
			//   M  MHM
			//       M
			
			helper.add(getTile(TileType.CHEESE,0,0));
			helper.add(getTile(TileType.CHEESE,1,0));
			helper.add(getTile(TileType.CHEESE,-1,1));
			helper.add(getTile(TileType.CHEESE,0,1));
			helper.add(getTile(TileType.CHEESE,1,1));
			helper.add(getTile(TileType.CHEESE,2,1));
			helper.add(getTile(TileType.CHEESE,3,1));
			helper.add(getTile(TileType.CHEESE,4,1));
			helper.add(getTile(TileType.CHEESE,5,1));
			helper.add(getTile(TileType.CHEESE,6,1));
			helper.add(getTile(TileType.CHEESE,0,2));
			helper.add(getTile(TileType.CHEESE,4,2));
			helper.add(getTile(TileType.CHEESE,4,3));			
			
			var cheeseList:Array = helper.list.concat();
			
			helper.add(getTile(TileType.MOUSE_BROWN,0,-1));
			helper.add(getTile(TileType.MOUSE_BROWN,1,-1));			
			helper.add(getTile(TileType.MOUSE_BROWN,-1,0));
			helper.add(getTile(TileType.MOUSE_BROWN,2,0));
			helper.add(getTile(TileType.MOUSE_BROWN,3,0));
			helper.add(getTile(TileType.MOUSE_GREY,4,0));
			helper.add(getTile(TileType.MOUSE_GREY,5,0));
			helper.add(getTile(TileType.MOUSE_GREY,6,0));
			helper.add(getTile(TileType.MOUSE_GREY,-2,1));
			helper.add(getTile(TileType.MOUSE_GREY,7,1));
			helper.add(getTile(TileType.MOUSE_GREY,-1,2));			
			helper.add(getTile(TileType.MOUSE_GREY,1,2));
			helper.add(getTile(TileType.MOUSE_GREY,2,2));
			helper.add(getTile(TileType.MOUSE_GREY,3,2));
			helper.add(getTile(TileType.MOUSE_GREY,5,2));
			helper.add(getTile(TileType.MOUSE_GREY,6,2));
			
			helper.add(getTile(TileType.MOUSE_GREY,0,3));			
			helper.add(getTile(TileType.MOUSE_GREY,3,3));
			helper.add(getTile(TileType.MOUSE_GREY,5,3));
			helper.add(getTile(TileType.MOUSE_GREY,4,4));
						
			var evaluator:PointEvaluatorT = new PointEvaluatorT(helper.map, helper.list);
				evaluator.callHandleCheese(cheeseList);
			
			assertEquals(260, evaluator.cheesePoints);
		}
		
		[Test]
		public function circleCheeseTest():void
		{
			//  MMM
			// MHHHM
			// MHMHM
			// MHHHM
			//  MMM 			
			
			helper.add(getTile(TileType.CHEESE,0,0));
			helper.add(getTile(TileType.CHEESE,1,0));
			helper.add(getTile(TileType.CHEESE,2,0));
			helper.add(getTile(TileType.CHEESE,0,1));
			helper.add(getTile(TileType.CHEESE,0,2));
			helper.add(getTile(TileType.CHEESE,1,2));
			helper.add(getTile(TileType.CHEESE,2,2));
			helper.add(getTile(TileType.CHEESE,2,1));
			
			var cheeseList:Array = helper.list.concat();
			
			helper.add(getTile(TileType.MOUSE_BROWN,0,-1));
			helper.add(getTile(TileType.MOUSE_BROWN,1,-1));
			helper.add(getTile(TileType.MOUSE_BROWN,2,-1));
			
			helper.add(getTile(TileType.MOUSE_BROWN,-1,0));
			helper.add(getTile(TileType.MOUSE_BROWN,-1,1));
			helper.add(getTile(TileType.MOUSE_BROWN,-1,2));
			
			helper.add(getTile(TileType.MOUSE_BROWN,0,3));
			helper.add(getTile(TileType.MOUSE_BROWN,1,3));
			helper.add(getTile(TileType.MOUSE_BROWN,2,3));	
			
			helper.add(getTile(TileType.MOUSE_BROWN,3,0));
			helper.add(getTile(TileType.MOUSE_BROWN,3,1));
			helper.add(getTile(TileType.MOUSE_BROWN,3,2));
			
			helper.add(getTile(TileType.MOUSE_BROWN,1,1
			));
			var evaluator:PointEvaluatorT = new PointEvaluatorT(helper.map, helper.list);
			evaluator.callHandleCheese(cheeseList);
			
			assertEquals(160, evaluator.cheesePoints);			
		}
		
		private function getTile(type:TileType, posX:Number=0, posY:Number=0):TileModel
		{
			var item:TileModel = new TileModel(new Tile(type));
				item.position = new Point(posX,posY);
			return item;	
		}
	}
}